home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2009 May / maximum-cd-2009-05.iso / DiscContents / Firefox Setup 3.0.6.exe / nonlocalized / chrome / browser.jar / content / browser / utilityOverlay.js < prev    next >
Encoding:
JavaScript  |  2008-04-22  |  20.8 KB  |  646 lines

  1. //@line 39 "/e/fx19rel/WINNT_5.2_Depend/mozilla/browser/base/content/utilityOverlay.js"
  2.  
  3. /**
  4.  * Communicator Shared Utility Library
  5.  * for shared application glue for the Communicator suite of applications
  6.  **/
  7.  
  8. var goPrefWindow = 0;
  9. var gBidiUI = false;
  10.  
  11. function getBrowserURL()
  12. {
  13.   return "chrome://browser/content/browser.xul";
  14. }
  15.  
  16. function goToggleToolbar( id, elementID )
  17. {
  18.   var toolbar = document.getElementById(id);
  19.   var element = document.getElementById(elementID);
  20.   if (toolbar)
  21.   {
  22.     var isHidden = toolbar.hidden;
  23.     toolbar.hidden = !isHidden;
  24.     document.persist(id, 'hidden');
  25.     if (element) {
  26.       element.setAttribute("checked", isHidden ? "true" : "false");
  27.       document.persist(elementID, 'checked');
  28.     }
  29.   }
  30. }
  31.  
  32. function getTopWin()
  33. {
  34.   var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1']
  35.                                 .getService(Components.interfaces.nsIWindowMediator);
  36.   return windowManager.getMostRecentWindow("navigator:browser");
  37. }
  38.  
  39. function openTopWin( url )
  40. {
  41.   openUILink(url, {})
  42. }
  43.  
  44. function getBoolPref ( prefname, def )
  45. {
  46.   try { 
  47.     var pref = Components.classes["@mozilla.org/preferences-service;1"]
  48.                        .getService(Components.interfaces.nsIPrefBranch);
  49.     return pref.getBoolPref(prefname);
  50.   }
  51.   catch(er) {
  52.     return def;
  53.   }
  54. }
  55.  
  56. // Change focus for this browser window to |aElement|, without focusing the
  57. // window itself.
  58. function focusElement(aElement) {
  59.   // This is a redo of the fix for jag bug 91884
  60.   var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
  61.                      .getService(Components.interfaces.nsIWindowWatcher);
  62.   if (window == ww.activeWindow)
  63.     aElement.focus();
  64.   else {
  65.     // set the element in command dispatcher so focus will restore properly
  66.     // when the window does become active
  67.     var cmdDispatcher = document.commandDispatcher;
  68.     if (aElement instanceof Window) {
  69.       cmdDispatcher.focusedWindow = aElement;
  70.       cmdDispatcher.focusedElement = null;
  71.     }
  72.     else if (aElement instanceof Element) {
  73.       cmdDispatcher.focusedWindow = aElement.ownerDocument.defaultView;
  74.       cmdDispatcher.focusedElement = aElement;
  75.     }
  76.   }
  77. }
  78.  
  79. // openUILink handles clicks on UI elements that cause URLs to load.
  80. function openUILink( url, e, ignoreButton, ignoreAlt, allowKeywordFixup, postData, referrerUrl )
  81. {
  82.   var where = whereToOpenLink(e, ignoreButton, ignoreAlt);
  83.   openUILinkIn(url, where, allowKeywordFixup, postData, referrerUrl);
  84. }
  85.  
  86.  
  87. /* whereToOpenLink() looks at an event to decide where to open a link.
  88.  *
  89.  * The event may be a mouse event (click, double-click, middle-click) or keypress event (enter).
  90.  *
  91.  * On Windows, the modifiers are:
  92.  * Ctrl        new tab, selected
  93.  * Shift       new window
  94.  * Ctrl+Shift  new tab, in background
  95.  * Alt         save
  96.  *
  97.  * You can swap Ctrl and Ctrl+shift by toggling the hidden pref
  98.  * browser.tabs.loadBookmarksInBackground (not browser.tabs.loadInBackground, which
  99.  * is for content area links).
  100.  *
  101.  * Middle-clicking is the same as Ctrl+clicking (it opens a new tab) and it is
  102.  * subject to the shift modifier and pref in the same way.
  103.  *
  104.  * Exceptions: 
  105.  * - Alt is ignored for menu items selected using the keyboard so you don't accidentally save stuff.  
  106.  *    (Currently, the Alt isn't sent here at all for menu items, but that will change in bug 126189.)
  107.  * - Alt is hard to use in context menus, because pressing Alt closes the menu.
  108.  * - Alt can't be used on the bookmarks toolbar because Alt is used for "treat this as something draggable".
  109.  * - The button is ignored for the middle-click-paste-URL feature, since it's always a middle-click.
  110.  */
  111. function whereToOpenLink( e, ignoreButton, ignoreAlt )
  112. {
  113.   if (!e)
  114.     e = { shiftKey:false, ctrlKey:false, metaKey:false, altKey:false, button:0 };
  115.  
  116.   var shift = e.shiftKey;
  117.   var ctrl =  e.ctrlKey;
  118.   var meta =  e.metaKey;
  119.   var alt  =  e.altKey && !ignoreAlt;
  120.  
  121.   // ignoreButton allows "middle-click paste" to use function without always opening in a new window.
  122.   var middle = !ignoreButton && e.button == 1;
  123.   var middleUsesTabs = getBoolPref("browser.tabs.opentabfor.middleclick", true);
  124.  
  125.   // Don't do anything special with right-mouse clicks.  They're probably clicks on context menu items.
  126.  
  127. //@line 167 "/e/fx19rel/WINNT_5.2_Depend/mozilla/browser/base/content/utilityOverlay.js"
  128.   if (ctrl || (middle && middleUsesTabs)) {
  129. //@line 169 "/e/fx19rel/WINNT_5.2_Depend/mozilla/browser/base/content/utilityOverlay.js"
  130.     if (shift)
  131.       return "tabshifted";
  132.     else
  133.       return "tab";
  134.   }
  135.   else if (alt) {
  136.     return "save";
  137.   }
  138.   else if (shift || (middle && !middleUsesTabs)) {
  139.     return "window";
  140.   }
  141.   else {
  142.     return "current";
  143.   }
  144. }
  145.  
  146. /* openUILinkIn opens a URL in a place specified by the parameter |where|.
  147.  *
  148.  * |where| can be:
  149.  *  "current"     current tab            (if there aren't any browser windows, then in a new window instead)
  150.  *  "tab"         new tab                (if there aren't any browser windows, then in a new window instead)
  151.  *  "tabshifted"  same as "tab" but in background if default is to select new tabs, and vice versa
  152.  *  "window"      new window
  153.  *  "save"        save to disk (with no filename hint!)
  154.  *
  155.  * allowThirdPartyFixup controls whether third party services such as Google's
  156.  * I Feel Lucky are allowed to interpret this URL. This parameter may be
  157.  * undefined, which is treated as false.
  158.  */
  159. function openUILinkIn( url, where, allowThirdPartyFixup, postData, referrerUrl )
  160. {
  161.   if (!where || !url)
  162.     return;
  163.  
  164.   if (where == "save") {
  165.     saveURL(url, null, null, true, null, referrerUrl);
  166.     return;
  167.   }
  168.   const Cc = Components.classes;
  169.   const Ci = Components.interfaces;
  170.  
  171.   var w = getTopWin();
  172.  
  173.   if (!w || where == "window") {
  174.     var sa = Cc["@mozilla.org/supports-array;1"].
  175.              createInstance(Ci.nsISupportsArray);
  176.  
  177.     var wuri = Cc["@mozilla.org/supports-string;1"].
  178.                createInstance(Ci.nsISupportsString);
  179.     wuri.data = url;
  180.  
  181.     sa.AppendElement(wuri);
  182.     sa.AppendElement(null);
  183.     sa.AppendElement(referrerUrl);
  184.     sa.AppendElement(postData);
  185.     sa.AppendElement(allowThirdPartyFixup);
  186.  
  187.     var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
  188.              getService(Ci.nsIWindowWatcher);
  189.  
  190.     ww.openWindow(w || window,
  191.                   getBrowserURL(),
  192.                   null,
  193.                   "chrome,dialog=no,all",
  194.                   sa);
  195.  
  196.     return;
  197.   }
  198.  
  199.   var loadInBackground = getBoolPref("browser.tabs.loadBookmarksInBackground", false);
  200.  
  201.   switch (where) {
  202.   case "current":
  203.     w.loadURI(url, referrerUrl, postData, allowThirdPartyFixup);
  204.     break;
  205.   case "tabshifted":
  206.     loadInBackground = !loadInBackground;
  207.     // fall through
  208.   case "tab":
  209.     var browser = w.getBrowser();
  210.     browser.loadOneTab(url, referrerUrl, null, postData, loadInBackground,
  211.                        allowThirdPartyFixup || false);
  212.     break;
  213.   }
  214.  
  215.   // Call focusElement(w.content) instead of w.content.focus() to make sure
  216.   // that we don't raise the old window, since the URI we just loaded may have
  217.   // resulted in a new frontmost window (e.g. "javascript:window.open('');").
  218.   focusElement(w.content);
  219. }
  220.  
  221. // Used as an onclick handler for UI elements with link-like behavior.
  222. // e.g. onclick="checkForMiddleClick(this, event);"
  223. function checkForMiddleClick(node, event)
  224. {
  225.   // We should be using the disabled property here instead of the attribute,
  226.   // but some elements that this function is used with don't support it (e.g.
  227.   // menuitem).
  228.   if (node.getAttribute("disabled") == "true")
  229.     return; // Do nothing
  230.  
  231.   if (event.button == 1) {
  232.     /* Execute the node's oncommand.
  233.      *
  234.      * XXX: we should use node.oncommand(event) once bug 246720 is fixed.
  235.      */
  236.     var fn = new Function("event", node.getAttribute("oncommand"));
  237.     fn.call(node, event);
  238.  
  239.     // If the middle-click was on part of a menu, close the menu.
  240.     // (Menus close automatically with left-click but not with middle-click.)
  241.     closeMenus(event.target);
  242.   }
  243. }
  244.  
  245. // Closes all popups that are ancestors of the node.
  246. function closeMenus(node)
  247. {
  248.   if ("tagName" in node) {
  249.     if (node.namespaceURI == "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
  250.     && (node.tagName == "menupopup" || node.tagName == "popup"))
  251.       node.hidePopup();
  252.  
  253.     closeMenus(node.parentNode);
  254.   }
  255. }
  256.  
  257. // Gather all descendent text under given document node.
  258. function gatherTextUnder ( root ) 
  259. {
  260.   var text = "";
  261.   var node = root.firstChild;
  262.   var depth = 1;
  263.   while ( node && depth > 0 ) {
  264.     // See if this node is text.
  265.     if ( node.nodeType == Node.TEXT_NODE ) {
  266.       // Add this text to our collection.
  267.       text += " " + node.data;
  268.     } else if ( node instanceof HTMLImageElement) {
  269.       // If it has an alt= attribute, use that.
  270.       var altText = node.getAttribute( "alt" );
  271.       if ( altText && altText != "" ) {
  272.         text = altText;
  273.         break;
  274.       }
  275.     }
  276.     // Find next node to test.
  277.     // First, see if this node has children.
  278.     if ( node.hasChildNodes() ) {
  279.       // Go to first child.
  280.       node = node.firstChild;
  281.       depth++;
  282.     } else {
  283.       // No children, try next sibling.
  284.       if ( node.nextSibling ) {
  285.         node = node.nextSibling;
  286.       } else {
  287.         // Last resort is our next oldest uncle/aunt.
  288.         node = node.parentNode.nextSibling;
  289.         depth--;
  290.       }
  291.     }
  292.   }
  293.   // Strip leading whitespace.
  294.   text = text.replace( /^\s+/, "" );
  295.   // Strip trailing whitespace.
  296.   text = text.replace( /\s+$/, "" );
  297.   // Compress remaining whitespace.
  298.   text = text.replace( /\s+/g, " " );
  299.   return text;
  300. }
  301.  
  302. function getShellService()
  303. {
  304.   var shell = null;
  305.   try {
  306.     shell = Components.classes["@mozilla.org/browser/shell-service;1"]
  307.       .getService(Components.interfaces.nsIShellService);
  308.   } catch (e) {dump("*** e = " + e + "\n");}
  309.   return shell;
  310. }
  311.  
  312. function isBidiEnabled() {
  313.   var rv = false;
  314.  
  315.   try {
  316.     var localeService = Components.classes["@mozilla.org/intl/nslocaleservice;1"]
  317.                                   .getService(Components.interfaces.nsILocaleService);
  318.     var systemLocale = localeService.getSystemLocale().getCategory("NSILOCALE_CTYPE").substr(0,3);
  319.  
  320.     switch (systemLocale) {
  321.       case "ar-":
  322.       case "he-":
  323.       case "fa-":
  324.       case "ur-":
  325.       case "syr":
  326.         rv = true;
  327.     }
  328.   } catch (e) {}
  329.  
  330.   // check the overriding pref
  331.   if (!rv)
  332.     rv = getBoolPref("bidi.browser.ui");
  333.  
  334.   return rv;
  335. }
  336.  
  337. function openAboutDialog()
  338. {
  339. //@line 391 "/e/fx19rel/WINNT_5.2_Depend/mozilla/browser/base/content/utilityOverlay.js"
  340.   window.openDialog("chrome://browser/content/aboutDialog.xul", "About", "centerscreen,chrome,resizable=no");
  341. //@line 393 "/e/fx19rel/WINNT_5.2_Depend/mozilla/browser/base/content/utilityOverlay.js"
  342. }
  343.  
  344. function openPreferences(paneID, extraArgs)
  345. {
  346.   var instantApply = getBoolPref("browser.preferences.instantApply", false);
  347.   var features = "chrome,titlebar,toolbar,centerscreen" + (instantApply ? ",dialog=no" : ",modal");
  348.  
  349.   var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
  350.                      .getService(Components.interfaces.nsIWindowMediator);
  351.   var win = wm.getMostRecentWindow("Browser:Preferences");
  352.   if (win) {
  353.     win.focus();
  354.     if (paneID) {
  355.       var pane = win.document.getElementById(paneID);
  356.       win.document.documentElement.showPane(pane);
  357.     }
  358.  
  359.     if (extraArgs && extraArgs["advancedTab"]) {
  360.       var advancedPaneTabs = win.document.getElementById("advancedPrefs");
  361.       advancedPaneTabs.selectedTab = win.document.getElementById(extraArgs["advancedTab"]);
  362.     }
  363.  
  364.     return win;
  365.   }
  366.  
  367.   return openDialog("chrome://browser/content/preferences/preferences.xul",
  368.                     "Preferences", features, paneID, extraArgs);
  369. }
  370.  
  371. function openAdvancedPreferences(tabID)
  372. {
  373.   return openPreferences("paneAdvanced", { "advancedTab" : tabID });
  374. }
  375.  
  376. /**
  377.  * Opens the release notes page for this version of the application.
  378.  * @param   event
  379.  *          The DOM Event that caused this function to be called, used to
  380.  *          determine where the release notes page should be displayed based
  381.  *          on modifiers (e.g. Ctrl = new tab)
  382.  */
  383. function openReleaseNotes(event)
  384. {
  385.   var formatter = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
  386.                             .getService(Components.interfaces.nsIURLFormatter);
  387.   var relnotesURL = formatter.formatURLPref("app.releaseNotesURL");
  388.   
  389.   openUILink(relnotesURL, event, false, true);
  390. }
  391.   
  392. /**
  393.  * Opens the update manager and checks for updates to the application.
  394.  */
  395. function checkForUpdates()
  396. {
  397.   var um = 
  398.       Components.classes["@mozilla.org/updates/update-manager;1"].
  399.       getService(Components.interfaces.nsIUpdateManager);
  400.   var prompter = 
  401.       Components.classes["@mozilla.org/updates/update-prompt;1"].
  402.       createInstance(Components.interfaces.nsIUpdatePrompt);
  403.  
  404.   // If there's an update ready to be applied, show the "Update Downloaded"
  405.   // UI instead and let the user know they have to restart the browser for
  406.   // the changes to be applied. 
  407.   if (um.activeUpdate && um.activeUpdate.state == "pending")
  408.     prompter.showUpdateDownloaded(um.activeUpdate);
  409.   else
  410.     prompter.checkForUpdates();
  411. }
  412.  
  413. function buildHelpMenu()
  414. {
  415.   // Enable/disable the "Report Web Forgery" menu item.  safebrowsing object
  416.   // may not exist in OSX
  417.   if (typeof safebrowsing != "undefined")
  418.     safebrowsing.setReportPhishingMenu();
  419.  
  420.   var updates = 
  421.       Components.classes["@mozilla.org/updates/update-service;1"].
  422.       getService(Components.interfaces.nsIApplicationUpdateService);
  423.   var um = 
  424.       Components.classes["@mozilla.org/updates/update-manager;1"].
  425.       getService(Components.interfaces.nsIUpdateManager);
  426.  
  427.   // Disable the UI if the update enabled pref has been locked by the 
  428.   // administrator or if we cannot update for some other reason
  429.   var checkForUpdates = document.getElementById("checkForUpdates");
  430.   var canUpdate = updates.canUpdate;
  431.   checkForUpdates.setAttribute("disabled", !canUpdate);
  432.   if (!canUpdate)
  433.     return; 
  434.  
  435.   var strings = document.getElementById("bundle_browser");
  436.   var activeUpdate = um.activeUpdate;
  437.   
  438.   // If there's an active update, substitute its name into the label
  439.   // we show for this item, otherwise display a generic label.
  440.   function getStringWithUpdateName(key) {
  441.     if (activeUpdate && activeUpdate.name)
  442.       return strings.getFormattedString(key, [activeUpdate.name]);
  443.     return strings.getString(key + "Fallback");
  444.   }
  445.   
  446.   // By default, show "Check for Updates..."
  447.   var key = "default";
  448.   if (activeUpdate) {
  449.     switch (activeUpdate.state) {
  450.     case "downloading":
  451.       // If we're downloading an update at present, show the text:
  452.       // "Downloading Firefox x.x..." otherwise we're paused, and show
  453.       // "Resume Downloading Firefox x.x..."
  454.       key = updates.isDownloading ? "downloading" : "resume";
  455.       break;
  456.     case "pending":
  457.       // If we're waiting for the user to restart, show: "Apply Downloaded
  458.       // Updates Now..."
  459.       key = "pending";
  460.       break;
  461.     }
  462.   }
  463.   checkForUpdates.label = getStringWithUpdateName("updatesItem_" + key);
  464.   if (um.activeUpdate && updates.isDownloading)
  465.     checkForUpdates.setAttribute("loading", "true");
  466.   else
  467.     checkForUpdates.removeAttribute("loading");
  468. }
  469.  
  470. function isElementVisible(aElement)
  471. {
  472.   if (!aElement)
  473.     return false;
  474.  
  475.   // If aElement or a direct or indirect parent is hidden or collapsed,
  476.   // height, width or both will be 0.
  477.   var bo = aElement.boxObject;
  478.   return (bo.height > 0 && bo.width > 0);
  479. }
  480.  
  481. function makeURLAbsolute(aBase, aUrl)
  482. {
  483.   // Note:  makeURI() will throw if aUri is not a valid URI
  484.   return makeURI(aUrl, null, makeURI(aBase)).spec;
  485. }
  486.  
  487. function getBrowserFromContentWindow(aContentWindow)
  488. {
  489.   var browsers = gBrowser.browsers;
  490.   for (var i = 0; i < browsers.length; i++) {
  491.     if (browsers[i].contentWindow == aContentWindow)
  492.       return browsers[i];
  493.   }
  494.   return null;
  495. }
  496.  
  497.  
  498. /**
  499.  * openNewTabWith: opens a new tab with the given URL.
  500.  *
  501.  * @param aURL
  502.  *        The URL to open (as a string).
  503.  * @param aDocument
  504.  *        The document from which the URL came, or null. This is used to set the
  505.  *        referrer header and to do a security check of whether the document is
  506.  *        allowed to reference the URL. If null, there will be no referrer
  507.  *        header and no security check.
  508.  * @param aPostData
  509.  *        Form POST data, or null.
  510.  * @param aEvent
  511.  *        The triggering event (for the purpose of determining whether to open
  512.  *        in the background), or null.
  513.  * @param aAllowThirdPartyFixup
  514.  *        If true, then we allow the URL text to be sent to third party services
  515.  *        (e.g., Google's I Feel Lucky) for interpretation. This parameter may
  516.  *        be undefined in which case it is treated as false.
  517.  * @param [optional] aReferrer
  518.  *        If aDocument is null, then this will be used as the referrer.
  519.  *        There will be no security check.
  520.  */ 
  521. function openNewTabWith(aURL, aDocument, aPostData, aEvent,
  522.                         aAllowThirdPartyFixup, aReferrer)
  523. {
  524.   if (aDocument)
  525.     urlSecurityCheck(aURL, aDocument.nodePrincipal);
  526.  
  527.   var prefSvc = Components.classes["@mozilla.org/preferences-service;1"]
  528.                           .getService(Components.interfaces.nsIPrefService);
  529.   prefSvc = prefSvc.getBranch(null);
  530.  
  531.   // should we open it in a new tab?
  532.   var loadInBackground = true;
  533.   try {
  534.     loadInBackground = prefSvc.getBoolPref("browser.tabs.loadInBackground");
  535.   }
  536.   catch(ex) {
  537.   }
  538.  
  539.   if (aEvent && aEvent.shiftKey)
  540.     loadInBackground = !loadInBackground;
  541.  
  542.   // As in openNewWindowWith(), we want to pass the charset of the
  543.   // current document over to a new tab. 
  544.   var wintype = document.documentElement.getAttribute("windowtype");
  545.   var originCharset;
  546.   if (wintype == "navigator:browser")
  547.     originCharset = window.content.document.characterSet;
  548.  
  549.   // open link in new tab
  550.   var referrerURI = aDocument ? aDocument.documentURIObject : aReferrer;
  551.   var browser = top.document.getElementById("content");
  552.   return browser.loadOneTab(aURL, referrerURI, originCharset, aPostData,
  553.                             loadInBackground, aAllowThirdPartyFixup || false);
  554. }
  555.  
  556. function openNewWindowWith(aURL, aDocument, aPostData, aAllowThirdPartyFixup,
  557.                            aReferrer)
  558. {
  559.   if (aDocument)
  560.     urlSecurityCheck(aURL, aDocument.nodePrincipal);
  561.  
  562.   // if and only if the current window is a browser window and it has a
  563.   // document with a character set, then extract the current charset menu
  564.   // setting from the current document and use it to initialize the new browser
  565.   // window...
  566.   var charsetArg = null;
  567.   var wintype = document.documentElement.getAttribute("windowtype");
  568.   if (wintype == "navigator:browser")
  569.     charsetArg = "charset=" + window.content.document.characterSet;
  570.  
  571.   var referrerURI = aDocument ? aDocument.documentURIObject : aReferrer;
  572.   return window.openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no",
  573.                            aURL, charsetArg, referrerURI, aPostData,
  574.                            aAllowThirdPartyFixup);
  575. }
  576.  
  577. /**
  578.  * isValidFeed: checks whether the given data represents a valid feed.
  579.  *
  580.  * @param  aData
  581.  *         An object representing a feed with title, href and type.
  582.  * @param  aPrincipal
  583.  *         The principal of the document, used for security check.
  584.  * @param  aIsFeed
  585.  *         Whether this is already a known feed or not, if true only a security
  586.  *         check will be performed.
  587.  */ 
  588. function isValidFeed(aData, aPrincipal, aIsFeed)
  589. {
  590.   if (!aData || !aPrincipal)
  591.     return false;
  592.  
  593.   if (!aIsFeed) {
  594.     var type = aData.type && aData.type.toLowerCase();
  595.     type = type.replace(/^\s+|\s*(?:;.*)?$/g, "");
  596.  
  597.     aIsFeed = (type == "application/rss+xml" ||
  598.                type == "application/atom+xml");
  599.  
  600.     if (!aIsFeed) {
  601.       // really slimy: general XML types with magic letters in the title
  602.       const titleRegex = /(^|\s)rss($|\s)/i;
  603.       aIsFeed = ((type == "text/xml" || type == "application/rdf+xml" ||
  604.                   type == "application/xml") && titleRegex.test(aData.title));
  605.     }
  606.   }
  607.  
  608.   if (aIsFeed) {
  609.     try {
  610.       urlSecurityCheck(aData.href, aPrincipal,
  611.                        Components.interfaces.nsIScriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL);
  612.     }
  613.     catch(ex) {
  614.       aIsFeed = false;
  615.     }
  616.   }
  617.  
  618.   if (type)
  619.     aData.type = type;
  620.  
  621.   return aIsFeed;
  622. }
  623.  
  624. // aCalledFromModal is optional
  625. function openHelpLink(aHelpTopic, aCalledFromModal) {
  626.   var url = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
  627.                       .getService(Components.interfaces.nsIURLFormatter)
  628.                       .formatURLPref("app.support.baseURL");
  629.   url += aHelpTopic;
  630.  
  631.   var where = aCalledFromModal ? "window" : "tab";
  632.   openUILinkIn(url, where);
  633. }
  634.  
  635. function openPrefsHelp() {
  636.   var prefs = Components.classes["@mozilla.org/preferences-service;1"]
  637.                         .getService(Components.interfaces.nsIPrefBranch2);
  638.  
  639.   // non-instant apply prefwindows are usually modal, so we can't open in the topmost window, 
  640.   // since its probably behind the window.
  641.   var instantApply = prefs.getBoolPref("browser.preferences.instantApply");
  642.  
  643.   var helpTopic = document.getElementsByTagName("prefwindow")[0].currentPane.helpTopic;
  644.   openHelpLink(helpTopic, !instantApply);
  645. }
  646.